<template>
  <div>
    <el-form ref="dynamicForm" :model="formModel" v-bind="getBindValue">
      <el-row v-bind="getRow">
        <template v-for="form in formProps.schemas">
          <el-col v-if="ifShow(form)" v-bind="{ ...form.colProps, ...getCol }">
            <el-form-item
              :key="form?.field"
              :prop="form?.field"
              :rules="computedRules(form)"
              v-bind="{ ...form, ...form.itemProps }"
            >
              <component
                v-if="!form.slot"
                :is="getComponent(form.component)"
                v-model="formModel[form.field]"
                v-bind="getComponentProps(form)"
                v-on="getEventHandlers(form)"
              >
              </component>
              <template v-else>
                <slot
                  :name="form.slot"
                  :fieldValue="{ text: formModel[form.field], record: formModel, column: form }"
                >
                </slot>
              </template>
            </el-form-item>
          </el-col>
        </template>
      </el-row>
    </el-form>
  </div>
</template>

<script lang="js" setup>
import { reactive, ref, toRaw, unref, onMounted, watch, useAttrs } from 'vue';
import { componentMap } from './componentMap';
import { basicProps } from './props'
const props = defineProps(basicProps);
const emit = defineEmits(['update:formDate', 'register']);
const formProps = ref({ ...props });
const formModel = ref(props.model);
const dynamicForm = ref(null);
const attrs = useAttrs();

// 监听 formModel 变化并发出事件
watch(
  formModel,
  newVal => {
    emit('update:formDate', newVal);
  },
  { deep: true }
);
const propsRef = ref({})

const getProps = computed(() => {
  let mergeProps = { ...props, ...formProps.value }
  if (mergeProps.labelWidth) {
    mergeProps.labelCol = undefined
  }
  return mergeProps
})
const getRow = computed(() => {
  const { baseRowStyle = {}, rowProps } = unref(getProps)
  return {
    style: baseRowStyle,
    ...rowProps,
  }
})
const getCol = computed(() => {
  const { baseColStyle = {}, baseColProps } = unref(getProps)
  return {
    style: baseColStyle,
    ...baseColProps,
  }
})
const getBindValue = computed(() => {
  const propsVal = { ...getProps.value, ...attrs, ...props, ...unref(getProps) }

  return propsVal
})
// 计算校验规则
const computedRules = (schema) => {
  const rules = schema.rules || []
  if (schema.required) {
    rules.push({ required: true, message: `请输入${schema?.label}`, trigger: ['blur', 'change'] })
  } else {
    return []
  }
  return rules
}
// 获取组件映射
function getComponent(component) {

  return componentMap.get(component) || component;
}

// 获取组件的属性配置
function getComponentProps(schema) {
  if (schema.component.includes('input')) {
    schema.componentProps.placeholder="请输入"+schema?.label
  }
  if (schema.component.includes('select')) {
    schema.componentProps.placeholder="请选择"+schema?.label
  }
  if (schema.component.includes('date')) {
    schema.componentProps.placeholder="请选择"+schema?.label
  }

  if (typeof schema.componentProps === 'function') {
    return schema.componentProps({ schema, formModel: formModel.value });
  }
  return schema.componentProps || {};
}

// 获取事件处理函数
function getEventHandlers(schema) {
  const handlers = {};
  const componentProps = getComponentProps(schema);

  // 检查是否包含事件处理函数
  Object.keys(componentProps).forEach(key => {

    if (typeof componentProps[key] === 'function') {

      handlers[key] = componentProps[key];
    }
  });

  return handlers;
}

// 判断是否为必填项
function isRequired(schema) {
  if (typeof schema.required === 'function') {
    return schema.required({ formModel: formModel.value });
  }
  return schema.required === true;
}

// 判断是否显示表单项
function ifShow(schema) {
  if (typeof schema?.show === 'function') {
    return schema?.show({ formModel: formModel.value });
  }
  return schema?.show !== false;
}

// 设置表单项配置
function setProps(obj) {
  formProps.value = { ...formProps.value, ...obj }
  formProps.value.schemas = obj?.schemas || [];
  console.log(propsRef.value, 'propsRef');
}

// 删除表单项配置
function removeSchemaByFiled(fieldsValue) {
  if (fieldsValue instanceof Array) {
    formProps.value.schemas = formProps.value.schemas.filter(item => !fieldsValue.includes(item.field));
      // 从formModel中删除对应的字段
    fieldsValue.forEach(field => {
      delete formModel.value[field];
    });
  }
  else {
    formProps.value.schemas = formProps.value.schemas.filter(item => item.field !== fieldsValue);
    // 从formModel中删除对应的字段
    delete formModel.value[fieldsValue];
  }

}


// 添加表单项配置
function addSchema(schema, first = false) {
  if (schema instanceof Array) {
    schema.forEach(newField => {
      const index = formProps.value.schemas.findIndex(oldField => oldField.field === newField.field);
      if (index !== -1) {

        formProps.value.schemas[index] = newField;
      } else {

        if (first) {
          formProps.value.schemas.unshift(newField);
        } else {
          formProps.value.schemas.push(newField);
        }
      }
    });
  } else {
    const hasInList = formProps.value.schemas.some(item => item.field === schema.field);
    if (!hasInList) {
      if (first) {
        formProps.value.schemas.unshift(schema);
      } else {
        formProps.value.schemas.push(schema);
      }
    }
  }
}


// 更新表单项配置
function updateSchema(fields) {
  if (fields instanceof Array) {

    fields.forEach(newField => {

      const index = formProps.value.schemas.findIndex(oldField => oldField.field === newField.field);
      if (index !== -1) {

        formProps.value.schemas[index] = newField;
      } else {

        formProps.value.schemas.push(newField);
      }
    });
  } else {

    const index = formProps.value.schemas.findIndex(item => item.field === fields.field);
    if (index !== -1) {
      formProps.value.schemas[index] = fields;
    } else {
      formProps.value.schemas.push(fields);
    }
  }
}


// 获取表单的值
function getFieldsValue() {
  return formModel.value;
}

// 设置表单的值
function setFieldsValue(values) {
  const fields = formProps.value.schemas.map(item => item.field).filter(Boolean);
  Object.keys(values).forEach(key => {
    const hasKey = Reflect.has(values, key);
    if (hasKey && fields.includes(key)) {
      formModel.value[key] = values[key];
    }
  });
}

// 清除验证
async function clearValidate(props) {
  await unref(dynamicForm).clearValidate(props);
}

// 重置表单
async function resetFields(props) {
  await unref(dynamicForm).resetFields(props);
}
// 重置表单
async function validate(props) {
  await unref(dynamicForm).validate(props);
}

// 定义表单操作类型
const formActionType = {
  ...dynamicForm.value,
  setProps,
  formModel,
  removeSchemaByFiled,
  addSchema,
  updateSchema,
  getFieldsValue,
  setFieldsValue,
  resetFields,
  clearValidate,
  validate,
};

// 页面挂载后触发 register 事件，传递表单操作类型
onMounted(() => {
  emit('register', formActionType);
});

defineExpose({
  setProps,
  removeSchemaByFiled,
  addSchema,
  updateSchema,
  getFieldsValue,
  validate,
});
</script>

<style scoped lang="scss">
:deep(.el-form) {
  .el-form-item {
    margin-bottom: 0;
  }
}
</style>
